<a class='main-nav-link focus-fix {selected ? "selected" : ""}'
   aria-label={ariaLabel}
   aria-current={selected}
   on:click="onClick(event)"
   rel="prefetch"
   {href} >
  <div class="nav-icon-and-label">
    <NavItemIcon
      {showBadge}
      {badgeNumber}
      {svg}
    />
    <span class="nav-link-label">{label}</span>
  </div>
  <div class="nav-indicator-wrapper {animationClasses}">
    <div class="nav-indicator" ref:indicator></div>
  </div>
</a>
<style>
  .main-nav-link {
    text-decoration: none;
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 1;
    flex-direction: column;
  }

  .nav-icon-and-label {
    padding: var(--nav-icon-pad-v) var(--nav-icon-pad-h);
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 1;
  }

  .main-nav-link.selected {
    background: var(--nav-a-selected-bg);
  }

  .main-nav-link.selected:hover {
    background: var(--nav-a-selected-bg-hover);
  }

  .nav-indicator-wrapper {
    width: 100%;
    height: var(--nav-indicator-height);
    display: flex;
  }

  .nav-indicator {
    flex: 1;
    transform-origin: left;
  }

  .nav-indicator {
    background: var(--nav-indicator-bg);
  }

  .nav-indicator-wrapper.animating > .nav-indicator {
    transition: transform 333ms ease-in-out;
    will-change: transform;
  }

  .main-nav-link:hover .nav-indicator {
    background: var(--nav-indicator-bg-hover);
  }

  .main-nav-link.selected .nav-indicator {
    background: var(--nav-indicator-bg-active);
  }

  /* Desktop/mouse only https://medium.com/@mezoistvan/finally-a-css-only-solution-to-hover-on-touchscreens-c498af39c31c */
  @media(hover: hover) and (pointer: fine) {
    .main-nav-link:hover .nav-indicator-wrapper.pre-animating {
      background: var(--nav-indicator-bg-hover);
    }
  }

  .main-nav-link:hover {
    background-color: var(--nav-a-bg-hover);
    text-decoration: none;
  }

  .main-nav-link:hover .nav-link-label {
    color: var(--nav-text-color-hover);
  }

  .main-nav-link:active {
    background-color: var(--nav-active-bg);
  }

  .main-nav-link.selected:active {
    background-color: var(--nav-a-selected-active-bg);
  }

  .nav-link-label {
    font-size: var(--nav-font-size);
    line-height: var(--nav-icon-size);
    color: var(--nav-text-color);
    padding-left: 10px;
    white-space: nowrap;
    overflow: visible;
    text-overflow: ellipsis;
  }

  @media (max-width: 991px) {
    .main-nav-link .nav-link-label {
      /* Copied from the sr-only styles in global.scss
       * the reason we explicitly leave this <span> in is because Voice Control on iOS does not
       * understand aria-labels very well, but it understands hidden text just fine
       */
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      border: 0;
    }
  }
</style>
<script>
  import NavItemIcon from './NavItemIcon.html'
  import { store } from '../_store/store.js'
  import { on, emit } from '../_utils/eventBus.js'
  import { mark, stop } from '../_utils/marks.js'
  import { doubleRAF } from '../_utils/doubleRAF.js'
  import { scrollToTop } from '../_utils/scrollToTop.js'
  import { normalizePageName } from '../_utils/normalizePageName.js'
  import { formatIntl } from '../_utils/formatIntl.js'
  import { classname } from '../_utils/classname.js'

  export default {
    oncreate () {
      on('animateNavPart1', this, ({ fromPage, toPage }) => {
        const { name } = this.get()
        const { reduceMotion } = this.store.get()
        if (fromPage === name && !reduceMotion) {
          this.animatePart1({ toPage })
        }
      })
      on('animateNavPart2', this, ({ toPage, fromRect }) => {
        const { name } = this.get()
        const { reduceMotion } = this.store.get()
        if (toPage === name && !reduceMotion) {
          this.animatePart2({ fromRect })
        }
      })
    },
    store: () => store,
    data: () => ({
      preAnimating: false,
      animating: false
    }),
    computed: {
      selected: ({ page, name }) => name === normalizePageName(page),
      ariaLabel: ({ selected, name, label, $numberOfNotifications, $numberOfFollowRequests }) => {
        const count = name === 'notifications'
          ? $numberOfNotifications
          : (name === 'community' ? $numberOfFollowRequests : 0)
        return formatIntl('intl.navItemLabel', {
          label,
          selected,
          name,
          count
        })
      },
      showBadge: ({ name, $hasNotifications, $hasFollowRequests }) => (
        (name === 'notifications' && $hasNotifications) || (name === 'community' && $hasFollowRequests)
      ),
      badgeNumber: ({ name, $numberOfNotifications, $numberOfFollowRequests }) => (
        (name === 'notifications' && $numberOfNotifications) || (name === 'community' && $numberOfFollowRequests) || 0
      ),
      animationClasses: ({ animating, preAnimating }) => classname(
        animating && 'animating',
        preAnimating && 'pre-animating'
      )
    },
    methods: {
      onClick (e) {
        const { selected } = this.get()
        if (!selected) {
          return
        }
        if (scrollToTop(/* smooth */ true)) {
          e.preventDefault()
          e.stopPropagation()
        }
      },
      animatePart1 ({ toPage }) {
        const indicator = this.refs.indicator
        mark('animateNavPart1 gBCR')
        const fromRect = indicator.getBoundingClientRect()
        stop('animateNavPart1 gBCR')
        emit('animateNavPart2', { fromRect, toPage })
      },
      animatePart2 ({ fromRect }) {
        const { indicator } = this.refs
        mark('animateNavPart2 gBCR')
        const toRect = indicator.getBoundingClientRect()
        stop('animateNavPart2 gBCR')
        const translateX = fromRect.left - toRect.left
        const scaleX = fromRect.width / toRect.width
        indicator.style.transform = `translateX(${translateX}px) scaleX(${scaleX})`
        const onTransitionEnd = () => {
          indicator.removeEventListener('transitionend', onTransitionEnd)
          this.set({ animating: false, preAnimating: false })
        }
        indicator.addEventListener('transitionend', onTransitionEnd)
        this.set({ preAnimating: true }) // avoids a flicker before the doubleRAF
        doubleRAF(() => {
          this.set({ animating: true })
          indicator.style.transform = ''
        })
      }
    },
    components: {
      NavItemIcon
    }
  }
</script>
